home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / gawk / gawk213s.zoo / gawk-src-2.13 / awk.y < prev    next >
Text File  |  1991-07-21  |  39KB  |  1,744 lines

  1. /*
  2.  * awk.y --- yacc/bison parser
  3.  */
  4.  
  5. /* 
  6.  * Copyright (C) 1986, 1988, 1989, 1991 the Free Software Foundation, Inc.
  7.  * 
  8.  * This file is part of GAWK, the GNU implementation of the
  9.  * AWK Progamming Language.
  10.  * 
  11.  * GAWK is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 1, or (at your option)
  14.  * any later version.
  15.  * 
  16.  * GAWK is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  * 
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with GAWK; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25.  
  26. %{
  27. #ifdef DEBUG
  28. #define YYDEBUG 12
  29. #endif
  30.  
  31. #define    YYMAXDEPTH    300
  32.  
  33. #include "awk.h"
  34.  
  35. static void yyerror (); /* va_alist */
  36. static char *get_src_buf P((void));
  37. static int yylex P((void));
  38. static NODE *node_common P((NODETYPE op));
  39. static NODE *snode P((NODE *subn, NODETYPE op, int index));
  40. static NODE *mkrangenode P((NODE *cpair));
  41. static NODE *make_for_loop P((NODE *init, NODE *cond, NODE *incr));
  42. static NODE *append_right P((NODE *list, NODE *new));
  43. static void func_install P((NODE *params, NODE *def));
  44. static void pop_var P((NODE *np, int freeit));
  45. static void pop_params P((NODE *params));
  46. static NODE *make_param P((char *name));
  47. static NODE *mk_rexp P((NODE *exp));
  48.  
  49. static int want_assign;        /* lexical scanning kludge */
  50. static int want_regexp;        /* lexical scanning kludge */
  51. static int can_return;        /* lexical scanning kludge */
  52. static int io_allowed = 1;    /* lexical scanning kludge */
  53. static char *lexptr;        /* pointer to next char during parsing */
  54. static char *lexend;
  55. static char *lexptr_begin;    /* keep track of where we were for error msgs */
  56. static char *lexeme;        /* beginning of lexeme for debugging */
  57. static char *thisline = NULL;
  58. #define YYDEBUG_LEXER_TEXT (lexeme)
  59. static int param_counter;
  60. static char *tokstart = NULL;
  61. static char *token = NULL;
  62. static char *tokend;
  63.  
  64. NODE *variables[HASHSIZE];
  65.  
  66. extern char *source;
  67. extern int sourceline;
  68. extern char *cmdline_src;
  69. extern char **srcfiles;
  70. extern int errcount;
  71. extern NODE *begin_block;
  72. extern NODE *end_block;
  73. %}
  74.  
  75. %union {
  76.     long lval;
  77.     AWKNUM fval;
  78.     NODE *nodeval;
  79.     NODETYPE nodetypeval;
  80.     char *sval;
  81.     NODE *(*ptrval)();
  82. }
  83.  
  84. %type <nodeval> function_prologue function_body
  85. %type <nodeval> rexp exp start program rule simp_exp
  86. %type <nodeval> non_post_simp_exp post_inc_dec_exp
  87. %type <nodeval> pattern 
  88. %type <nodeval>    action variable param_list
  89. %type <nodeval>    rexpression_list opt_rexpression_list
  90. %type <nodeval>    expression_list opt_expression_list
  91. %type <nodeval>    statements statement if_statement opt_param_list 
  92. %type <nodeval> opt_exp opt_variable regexp 
  93. %type <nodeval> input_redir output_redir
  94. %type <nodetypeval> print
  95. %type <sval> func_name
  96.  
  97. %token <sval> FUNC_CALL NAME REGEXP
  98. %token <lval> ERROR
  99. %token <nodeval> YNUMBER YSTRING
  100. %token <nodetypeval> RELOP APPEND_OP
  101. %token <nodetypeval> ASSIGNOP MATCHOP NEWLINE CONCAT_OP
  102. %token <nodetypeval> LEX_BEGIN LEX_END LEX_IF LEX_ELSE LEX_RETURN LEX_DELETE
  103. %token <nodetypeval> LEX_WHILE LEX_DO LEX_FOR LEX_BREAK LEX_CONTINUE
  104. %token <nodetypeval> LEX_PRINT LEX_PRINTF LEX_NEXT LEX_EXIT LEX_FUNCTION
  105. %token <nodetypeval> LEX_GETLINE
  106. %token <nodetypeval> LEX_IN
  107. %token <lval> LEX_AND LEX_OR INCREMENT DECREMENT
  108. %token <lval> LEX_BUILTIN LEX_LENGTH
  109.  
  110. /* these are just yylval numbers */
  111.  
  112. /* Lowest to highest */
  113. %right ASSIGNOP
  114. %right '?' ':'
  115. %left LEX_OR
  116. %left LEX_AND
  117. %left LEX_GETLINE
  118. %nonassoc LEX_IN
  119. %left FUNC_CALL LEX_BUILTIN LEX_LENGTH
  120. %nonassoc MATCHOP
  121. %nonassoc RELOP '<' '>' '|' APPEND_OP
  122. %left CONCAT_OP
  123. %left YSTRING YNUMBER
  124. %left '+' '-'
  125. %left '*' '/' '%'
  126. %right '!' UNARY
  127. %right '^'
  128. %left INCREMENT DECREMENT
  129. %left '$'
  130. %left '(' ')'
  131. %%
  132.  
  133. start
  134.     : opt_nls program opt_nls
  135.         { expression_value = $2; }
  136.     ;
  137.  
  138. program
  139.     : rule
  140.         { 
  141.             if ($1 != NULL)
  142.                 $$ = $1;
  143.             else
  144.                 $$ = NULL;
  145.             yyerrok;
  146.         }
  147.     | program rule
  148.         /* add the rule to the tail of list */
  149.         {
  150.             if ($2 == NULL)
  151.                 $$ = $1;
  152.             else if ($1 == NULL)
  153.                 $$ = $2;
  154.             else {
  155.                 if ($1->type != Node_rule_list)
  156.                     $1 = node($1, Node_rule_list,
  157.                         (NODE*)NULL);
  158.                 $$ = append_right ($1,
  159.                    node($2, Node_rule_list,(NODE *) NULL));
  160.             }
  161.             yyerrok;
  162.         }
  163.     | error    { $$ = NULL; }
  164.     | program error { $$ = NULL; }
  165.     ;
  166.  
  167. rule
  168.     : LEX_BEGIN { io_allowed = 0; }
  169.       action
  170.       {
  171.         if (begin_block) {
  172.             if (begin_block->type != Node_rule_list)
  173.                 begin_block = node(begin_block, Node_rule_list,
  174.                     (NODE *)NULL);
  175.             (void) append_right (begin_block, node(
  176.                 node((NODE *)NULL, Node_rule_node, $3),
  177.                 Node_rule_list, (NODE *)NULL) );
  178.         } else
  179.             begin_block = node((NODE *)NULL, Node_rule_node, $3);
  180.         $$ = NULL;
  181.         io_allowed = 1;
  182.         yyerrok;
  183.       }
  184.     | LEX_END { io_allowed = 0; }
  185.       action
  186.       {
  187.         if (end_block) {
  188.             if (end_block->type != Node_rule_list)
  189.                 end_block = node(end_block, Node_rule_list,
  190.                     (NODE *)NULL);
  191.             (void) append_right (end_block, node(
  192.                 node((NODE *)NULL, Node_rule_node, $3),
  193.                 Node_rule_list, (NODE *)NULL));
  194.         } else
  195.             end_block = node((NODE *)NULL, Node_rule_node, $3);
  196.         $$ = NULL;
  197.         io_allowed = 1;
  198.         yyerrok;
  199.       }
  200.     | LEX_BEGIN statement_term
  201.       {
  202.         warning("BEGIN blocks must have an action part");
  203.         errcount++;
  204.         yyerrok;
  205.       }
  206.     | LEX_END statement_term
  207.       {
  208.         warning("END blocks must have an action part");
  209.         errcount++;
  210.         yyerrok;
  211.       }
  212.     | pattern action
  213.         { $$ = node ($1, Node_rule_node, $2); yyerrok; }
  214.     | action
  215.         { $$ = node ((NODE *)NULL, Node_rule_node, $1); yyerrok; }
  216.     | pattern statement_term
  217.         {
  218.           $$ = node ($1,
  219.                  Node_rule_node,
  220.                  node(node(node(make_number(0.0),
  221.                         Node_field_spec,
  222.                         (NODE *) NULL),
  223.                     Node_expression_list,
  224.                     (NODE *) NULL),
  225.                   Node_K_print,
  226.                   (NODE *) NULL));
  227.           yyerrok;
  228.         }
  229.     | function_prologue function_body
  230.         {
  231.             func_install($1, $2);
  232.             $$ = NULL;
  233.             yyerrok;
  234.         }
  235.     ;
  236.  
  237. func_name
  238.     : NAME
  239.         { $$ = $1; }
  240.     | FUNC_CALL
  241.         { $$ = $1; }
  242.     ;
  243.         
  244. function_prologue
  245.     : LEX_FUNCTION 
  246.         {
  247.             param_counter = 0;
  248.         }
  249.       func_name '(' opt_param_list r_paren opt_nls
  250.         {
  251.             $$ = append_right(make_param($3), $5);
  252.             can_return = 1;
  253.         }
  254.     ;
  255.  
  256. function_body
  257.     : l_brace statements r_brace opt_semi
  258.       {
  259.         $$ = $2;
  260.         can_return = 0;
  261.       }
  262.     ;
  263.  
  264.  
  265. pattern
  266.     : exp
  267.         { $$ = $1; }
  268.     | exp comma exp
  269.         { $$ = mkrangenode ( node($1, Node_cond_pair, $3) ); }
  270.     ;
  271.  
  272. regexp
  273.     /*
  274.      * In this rule, want_regexp tells yylex that the next thing
  275.      * is a regexp so it should read up to the closing slash.
  276.      */
  277.     : '/'
  278.         { ++want_regexp; }
  279.       REGEXP '/'
  280.         {
  281.           NODE *n;
  282.  
  283.           getnode(n);
  284.           n->type = Node_regex;
  285.           n->re_exp = make_string($3, strlen($3));
  286.           n->re_reg = mk_re_parse($3, 0);
  287.           n->re_text = NULL;
  288.           n->re_flags = CONST;
  289.           n->re_cnt = 1;
  290.           $$ = n;
  291.         }
  292.     ;
  293.  
  294. action
  295.     : l_brace statements r_brace opt_semi
  296.         { $$ = $2 ; }
  297.     | l_brace r_brace opt_semi
  298.         { $$ = NULL; }
  299.     ;
  300.  
  301. statements
  302.     : statement
  303.         { $$ = $1; }
  304.     | statements statement
  305.         {
  306.             if ($1 == NULL || $1->type != Node_statement_list)
  307.                 $1 = node($1, Node_statement_list,(NODE *)NULL);
  308.                 $$ = append_right($1,
  309.                 node( $2, Node_statement_list, (NODE *)NULL));
  310.                 yyerrok;
  311.         }
  312.     | error
  313.         { $$ = NULL; }
  314.     | statements error
  315.         { $$ = NULL; }
  316.     ;
  317.  
  318. statement_term
  319.     : nls
  320.     | semi opt_nls
  321.     ;
  322.  
  323. statement
  324.     : semi opt_nls
  325.         { $$ = NULL; }
  326.     | l_brace r_brace
  327.         { $$ = NULL; }
  328.     | l_brace statements r_brace
  329.         { $$ = $2; }
  330.     | if_statement
  331.         { $$ = $1; }
  332.     | LEX_WHILE '(' exp r_paren opt_nls statement
  333.         { $$ = node ($3, Node_K_while, $6); }
  334.     | LEX_DO opt_nls statement LEX_WHILE '(' exp r_paren opt_nls
  335.         { $$ = node ($6, Node_K_do, $3); }
  336.     | LEX_FOR '(' NAME LEX_IN NAME r_paren opt_nls statement
  337.       {
  338.         $$ = node ($8, Node_K_arrayfor, make_for_loop(variable($3,1),
  339.             (NODE *)NULL, variable($5,1)));
  340.       }
  341.     | LEX_FOR '(' opt_exp semi exp semi opt_exp r_paren opt_nls statement
  342.       {
  343.         $$ = node($10, Node_K_for, (NODE *)make_for_loop($3, $5, $7));
  344.       }
  345.     | LEX_FOR '(' opt_exp semi semi opt_exp r_paren opt_nls statement
  346.       {
  347.         $$